###################################################################################################################

#    Standalong perl script to test if Apache Server is vulnerable to CVE-2011-4317
#    Author: Prutha Parikh
#    Usage: perl apache_CVE-2011-4317.pl -h <ip or hostname of vuln target> [-p <port>] [-d <internal web server url>]

###################################################################################################################

use IO::Socket;
use Getopt::Long;

my $host = undef;
my $port = 80;
my $domain;

sub usage {

	my $usage = <<"EOF";
Test for Apache/IIS Reverse Proxy Misconfigured Rules
USAGE:
perl apache_CVE-2011-4317.pl -h <ip or hostname of vuln target> [-p <port>] [-d <internal web server url>]
example: perl apache_CVE-2011-4317.pl -h www.testsite.com
example: perl apache_CVE-2011-4317.pl -h 10.2.2.3 -p 8080
EOF

print $usage."\n";
}

sub rndStr{ join'', @_[ map{ rand @_ } 1 .. shift ] }

sub ParseOptions()
{
	if(! defined($host))
	{
		print "Please provide a valid hostname or IP address\n";
		usage();
		exit 1;
	}
}
#Read the command line options
GetOptions('h=s' => \$host,
	'p=s' => \$port,
	'd=s' => \$domain
);
#Validate the command line options
ParseOptions();

#Function to test whether the target is vulnerable or not. 
sub apachereverseproxy 
{
	my $sock = IO::Socket::INET->new(PeerAddr => $host,
        	                         PeerPort => $port,
                	     		 Proto    => 'tcp');
	if(! defined $sock)
	{
		print "ERR: Could not establish connection on $host and $port using tcp protocol, please make sure host and port are valid.\n";
		usage();
		exit 1;
	}

	my @chars = ("A".."Z", "a".."z");
	my $random_domain_string;
	$random_domain_string .= $chars[rand @chars] for 1..8;

	$random_string = rndStr 8, 'a'..'z', 'A'..'Z';
	if(!defined $domain)
	{
		#Generate a random string for the internal domain.
	        my @chars = ("A".."Z", "a".."z");
	        my $random_domain_string;
        	$random_domain_string .= $chars[rand @chars] for 1..8;
      		$random_string = rndStr 8, 'a'..'z', 'A'..'Z';
		my $req = "GET ".$random_string.":\@www.".$random_domain_string.".com HTTP/1.1\r\nHost: $host\r\nConnection: close\r\n\r\n";
		print "REQUEST : $req\n";
		print $sock $req;
		my $res = "";
		while (<$sock>)
		{
			$res .= $_;
		}
		print "RESPONSE : $res\n";
		if ($res =~ /502/) {
			print "RESULT : Target appears to be vulnerable to Apache HTTP Server Reverse Proxy/Rewrite URL Validation Security Issue (CVE-2011-4317),\
and might have misconfigured reverse proxy rules\n";
			return 1;	
		} else {
			return 0;	
		}
	}	
	else
	{
		my $req = "GET ".$random_string.":\@$domain HTTP/1.1\r\nHost: $host\r\nConnection: close\r\n\r\n";
		print $req;
		print $sock $req;
		my $res = "";
		while(<$sock>)
		{
			$res .= $_;
		}
		print "RESPONSE: $res\n";
		if ($res =~ /200/ || $res =~ /502/) {
        		print "RESULT : Target appears to be vulnerable to Apache HTTP Server Reverse Proxy/Rewrite URL Validation Security Issue (CVE-2011-4317),\
and might have misconfigured reverse proxy rules\n";
        		return 1;
		} else {	
        		return 0;
		}
	}
}

$value = apachereverseproxy();
if ($value == 0) {
	print "RESULT : Target DOES NOT appear to be vulnerable to Apache HTTP Server Reverse Proxy/Rewrite URL Validation Security Issue (CVE-2011-4317)\n";
	exit;	
}
